package com.scorpio.baselibrary.utils;

import android.content.Context;
import android.content.SharedPreferences;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * SharedPreferences 快速存储工具
 * created by 包子 on 2018/12/6
 */
public class AppDataUtil {
    private Context mContext;
    //缓存反射对象
    private final HashMap<String, List<Field>> mFields = new HashMap<>();
    private static AppDataUtil mAppDataUtil;

    public static AppDataUtil getInstance() {
        if (mAppDataUtil == null) {
            mAppDataUtil = new AppDataUtil();
        }
        return mAppDataUtil;
    }

    /**
     * 第一次使用需要调用 在application调用
     */
    public void init(Context context) {
        this.mContext = context;
    }

    public void commitData(Object obj) {
        commitData(obj, "");
    }

    public void commitData(Object obj, String name) {
        commitData(obj, name, Context.MODE_PRIVATE);
    }

    /**
     * 存储数据
     * @param obj 封装数据对象
     * @param name 存储名称
     * @param mode 缓存模式
     * @return
     */
    public void commitData(Object obj, String name, int mode) {
        name = obj.getClass().getSimpleName() + "-" + name == null ? "" : name;
        List<Field> fields = getField(obj.getClass());
        SharedPreferences sharedPre = mContext.getSharedPreferences(name, mode);
        try {
            SharedPreferences.Editor editor = sharedPre.edit();
            for (Field field : fields) {
                String key = field.getName();
                if (field.getType() == String.class) {
                    editor.putString(key, (String) field.get(obj));
                } else if (field.getType() == int.class) {
                    editor.putInt(key, (int) field.get(obj));
                } else if (field.getType() == long.class) {
                    editor.putLong(key, (long) field.get(obj));
                } else if (field.getType() == float.class) {
                    editor.putFloat(key, (float) field.get(obj));
                } else if (field.getType() == boolean.class) {
                    editor.putBoolean(key, (boolean) field.get(obj));
                }
            }
            editor.commit();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }


    public Object readData(Object obj) {
        return readData(obj, "");
    }

    public Object readData(Object obj, String name) {
        return readData(obj, name, Context.MODE_PRIVATE);
    }

    /**
     * 读取数据
     * @param obj 封装数据对象
     * @param name 存储名称
     * @param mode 缓存模式
     * @return
     */
    public Object readData(Object obj, String name, int mode) {
        name = obj.getClass().getSimpleName() + "-" + name == null ? "" : name;
        List<Field> fields = getField(obj.getClass());
        SharedPreferences sharedPre = mContext.getSharedPreferences(name, mode);
        try {
            for (Field field : fields) {
                String key = field.getName();
                if (!sharedPre.contains(key)) continue;
                if (field.getType() == String.class) {
                    field.set(obj, sharedPre.getString(key, (String) field.get(obj)));
                } else if (field.getType() == int.class) {
                    field.set(obj, sharedPre.getInt(key, (int) field.get(obj)));
                } else if (field.getType() == long.class) {
                    field.set(obj, sharedPre.getLong(key, (long) field.get(obj)));
                } else if (field.getType() == float.class) {
                    field.set(obj, sharedPre.getFloat(key, (float) field.get(obj)));
                } else if (field.getType() == boolean.class) {
                    field.set(obj, sharedPre.getBoolean(key, (boolean) field.get(obj)));
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return obj;
    }

    public void clearCache(Class aClass) {
        clearCache(aClass, "");
    }

    /**
     * 清空指定缓存
     * @param aClass 封装数据对象类型
     * @param name 存储名称
     */
    public void clearCache(Class aClass, String name) {
        name = aClass.getSimpleName() + "-" + name == null ? "" : name;
        SharedPreferences sharedPre = mContext.getSharedPreferences(name, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPre.edit();
        editor.clear();
        editor.commit();
    }

    /**
     * 从缓存中获取反射的变量
     * @param aClass
     * @return
     */
    private List<Field> getField(Class aClass) {
        List<Field> fields = mFields.get(aClass.getName());
        if (fields == null) {
            fields = new ArrayList<>();
            Field[] checkFields = aClass.getDeclaredFields();
            for (int i = checkFields.length - 1; i >= 0; i--) {
                checkFields[i].setAccessible(true);
                fields.add(checkFields[i]);
            }
            mFields.put(aClass.getName(), fields);
        }
        return fields;
    }
}
